/* eslint-disable no-loop-func */
/**
 * @module utils/CadAnalyzeUtil
 * @desc Cad导入结果解析工具
 */

import { addTextFieldPropertiesToFeatures } from './LayerUtil';

/**
 * 格式化图层坐标数据
 * @param {Object} datas 图层数据
 * @ignore
 */
function formatCoords(datas) {
  for (let key in datas) {
    let data = datas[key];
    for (let type in data) {
      let layer = data[type];
      layer.forEach((item) => {
        let sdoGtype = item.sdoGtype;
        let coordsList = sdoGtype === 2001 ? item.sdoPointType : item.sdoOrdinates;
        // 转换坐标格式：[lng, lat, lng, lat, ...] => [[lng, lat], [lng, lat], ...]
        let coords = [];
        for (let i = 0; i < coordsList.length; i += 2) {
          let lng = coordsList[i];
          let lat = coordsList[i + 1];
          coords.push([lng, lat]);
        }
        item.coordsList = coords;
      });
    }
  }
}

/**
 * 转换大地2000坐标到思极坐标
 * @param {Array} list
 * @returns
 */
export function convert2000ToSg(list) {
  let convertTask = new SGMap.ConvertTask();
  let promiseList = [];
  return new Promise((resolve) => {
    list.forEach((item) => {
      promiseList.push(new Promise((resolve2) => {
        convertTask.convertCoord(item.list, { from: 1 }).then((res) => {
          resolve2({ list: res, record: item.record });
        });
      }));
    });
    Promise.all(promiseList).then((res) => {
      resolve(res);
    });
  });
}
/**
 * 转换图层坐标数据（大地2000 -> 思极坐标）
 * @param {Object} datas 图层数据
 * @ignore
 */
async function convertCoords(datas) {
  // 需要转换的坐标集合
  let convertList = [];
  // 每次的转换坐标，200个坐标一组
  let tempList = [];
  // 记录每次转换的坐标对应的原图层对象位置
  let tempRecord = {};
  // 遍历所有坐标数据，对坐标数据进行封装
  // tempList记录转换坐标数组；
  // tempRecord记录转换坐标对应原图层对象位置，key：坐标转换数组中的起始下标至结束下标；value：原图层对象的key->key->坐标数组下标->起始下标->结束下标，用“%|%”分割；
  // 当tempList长度大于200时进行一次封装，将转换坐标和记录对象存入转换集合，并清空tempList和tempRecord。
  for (let key in datas) {
    let data = datas[key];
    for (let type in data) {
      let layer = data[type];
      layer.forEach((item, index) => {
        let sdoGtype = item.sdoGtype;
        let coordsList = sdoGtype === 2001 ? item.sdoPointType : item.sdoOrdinates;
        item.coordsList = Array(coordsList.length / 2);
        // 转换坐标格式：[lng, lat, lng, lat, ...] => [[lng, lat], [lng, lat], ...]
        let coords = [];
        for (let i = 0; i < coordsList.length; i += 2) {
          let lng = coordsList[i];
          let lat = coordsList[i + 1];
          coords.push([lng, lat]);
        }
        // 当转换坐标数量大于200时，对前200个坐标进行一次封装
        let start = 0;
        while (tempList.length + coords.length > 200) {
          let end = 200 - tempList.length;
          let current = coords.splice(0, end);
          tempRecord[`${tempList.length}-199`] = `${key}%|%${type}%|%${index}%|%${start}`;
          convertList.push({
            list: tempList.concat(current),
            record: Object.assign({}, tempRecord)
          });
          tempRecord = {};
          tempList = [];
          start = start + end;
        }
        // 将当前坐标存入转换坐标数组
        tempRecord[`${tempList.length}-${tempList.length + coords.length - 1}`] =
          `${key}%|%${type}%|%${index}%|%${start}`;
        tempList = tempList.concat(coords);
        // 当转换坐标数量等于200时，进行一次封装
        if (tempList.length === 200) {
          convertList.push({
            list: [].concat(tempList),
            record: Object.assign({}, tempRecord)
          });
          tempRecord = {};
          tempList = [];
        }
      });
    }
  }
  // 封装剩余坐标
  convertList.push({
    list: tempList,
    record: tempRecord
  });
  // 调用思极地图接口转换经纬度坐标
  let result = [];
  while (convertList.length > 0) {
    let actionList = convertList.splice(0, 500);
    let res = await convert2000ToSg(actionList);
    result = result.concat(res);
  }
  // 将转换过的坐标回填到原图层数据中
  result.forEach((item) => {
    Object.keys(item.record).forEach((key) => {
      let indexs = key.split('-');
      let start = Number(indexs[0]);
      let end = Number(indexs[1]);
      let paths = item.record[key].split('%|%');
      let data = datas[paths[0]][paths[1]][paths[2]];
      let length = end - start + 1;
      for (let i = 0; i < length; i++) {
        data.coordsList[Number(paths[3]) + i] = item.list[start + i];
      }
    });
  });
}

/**
 * 获取图层数据
 * @param {Object} layerData 图层数据
 * @param {Object} tool 工具箱
 * @ignore
 */
function formatLayerData(layerData, tool) {
  let layerMapping = {};
  for (let key in layerData) {
    let data = layerData[key];
    let layerItems = [];
    for (let type in data) {
      let items = data[type];
      let features = items.map((item) => tool.formatLayerFeature(item, key, type));
      features = features.filter((item) => item !== null);
      layerItems = layerItems.concat(features);
    }
    layerMapping[key] = layerItems;
  }
  let features = [];
  for (let key in layerMapping) {
    features = features.concat(layerMapping[key]);
  }
  features = addTextFieldPropertiesToFeatures(features, 'label');
  return { layerMapping, features };
}

/**
 * 解析Cad导入数据
 * @param {Object} datas Cad导入数据
 * @param {Object} tool 工具箱
 */
export async function analyzeResult(datas, tool) {
  let layerTypes = Object.keys(datas.layerType);
  let layerData = datas.layerData;
  if (tool.option.coordinate === 'DEFAULT') {
    formatCoords(layerData);
  } else {
    await convertCoords(layerData);
  }
  let { layerMapping, features } = formatLayerData(layerData, tool);
  return {
    layerTypes: layerTypes,
    layerData: layerMapping,
    features: features
  };
}